package com.jyu.apts.config;

import java.util.LinkedHashMap;
import java.util.Map;

import javax.servlet.Filter;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import com.jyu.apts.shiro.ShiroRealm;
import com.jyu.apts.shiro.ShiroWebSessionManager;
import com.jyu.apts.utils.PasswordEntryUtil;

@Configuration
public class ShiroConfig {
	
	@Bean
    public ShiroFilterFactoryBean shiroFilter(org.apache.shiro.mgt.SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //设置安全管理器
        shiroFilterFactoryBean.setSecurityManager( securityManager);
        //默认跳转到登陆页面
        shiroFilterFactoryBean.setLoginUrl("/login_html");
        //登陆成功后的页面
        shiroFilterFactoryBean.setSuccessUrl("/index_html");
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");

        //自定义过滤器
       Map<String,Filter> filterMap=new LinkedHashMap<>();
       shiroFilterFactoryBean.setFilters(filterMap);
       //权限控制map
       Map<String,String> filterChainDefinitionMap=new LinkedHashMap<>();
       // 配置不会被拦截的链接 顺序判断
       //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
       filterChainDefinitionMap.put("/logout", "logout");
       filterChainDefinitionMap.put("/logoutWithResult", "logout");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

   /**
    * 核心的安全事务管理器
    * @return
    */
    @Bean
   public org.apache.shiro.mgt.SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager ();
        //设置realm
        securityManager.setRealm(myShiroRealm());
        securityManager.setSessionManager(new ShiroWebSessionManager());
        return securityManager;
    }


   /**
    * 身份认证Realm
    * @return
    */
   @Bean
   public ShiroRealm myShiroRealm(  ){
	   ShiroRealm myShiroRealm = new ShiroRealm();
       myShiroRealm.setCredentialsMatcher(  hashedCredentialsMatcher() );
       return myShiroRealm;
   }



   /**
    * 哈希密码比较器。在myShiroRealm中作用参数使用
    * 登陆时会比较用户输入的密码，跟数据库密码配合盐值salt解密后是否一致。
    * @return
    */
   @Bean
   public HashedCredentialsMatcher hashedCredentialsMatcher(){
	   HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
	   hashedCredentialsMatcher.setHashAlgorithmName(PasswordEntryUtil.algorithmName);//散列算法
	   hashedCredentialsMatcher.setHashIterations(PasswordEntryUtil.hashIterations);//散列的次数
       return hashedCredentialsMatcher;
   }

//   //注入缓存
//   @Bean
//   public EhCacheManager ehCacheManager(){
//       System.out.println("ShiroConfiguration.getEhCacheManager()执行");
//       EhCacheManager cacheManager=new EhCacheManager();
//       cacheManager.setCacheManagerConfigFile("classpath:config/ehcache-shiro.xml");
//       return cacheManager;
//   }

   /**
    *  开启shiro aop注解支持.
    *  使用代理方式;所以需要开启代码支持;否则@RequiresRoles等注解无法生效
    * @param securityManager
    * @return
    */
   @Bean
   public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(org.apache.shiro.mgt.SecurityManager securityManager){
       AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
       authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
       return authorizationAttributeSourceAdvisor;
   }

   /**
    * Shiro生命周期处理器
    * @return
    */
   @Bean
   public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
       return new LifecycleBeanPostProcessor();
   }

   /**
    * 自动创建代理
    * @return
    */
   @Bean
   @DependsOn({"lifecycleBeanPostProcessor"})
   public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
       DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
       advisorAutoProxyCreator.setProxyTargetClass(true);
       return advisorAutoProxyCreator;
   }
}
